package com.kdgc.energy.dmm.query;

import com.kdgc.energy.dmm.Environment;
import com.kdgc.energy.dmm.func.Function;
import com.kdgc.energy.dmm.func.Functions;
import com.kdgc.energy.dmm.lambda.SerializedFunction;
import lombok.Getter;
import org.apache.metamodel.query.FromItem;
import org.apache.metamodel.query.SelectItem;

/**
 * @author xu.wenchang
 * @version 1.0 2022/04/16
 */
public class Select {
    private Query query;
    
    @Getter
    private SelectItem delegate;
    
    private Select(SelectItem selectItem) {
        this.delegate = selectItem;
    }
    
    public <T, R> Select(SerializedFunction<T, R> sf) {
        this.delegate = new SelectItem(null, Environment.get(sf));
    }
    
    public <T, R> Select(Function function, SerializedFunction<T, R> sf) {
        this.delegate = new SelectItem(Functions.toMetaModelFunctionType(function), Environment.get(sf));
    }
    
    public <T, R> Select(Function function, Object[] functionParameters, SerializedFunction<T, R> sf) {
        this.delegate = new SelectItem(Functions.toMetaModelFunctionType(function), functionParameters, Environment.get(sf));
    }
    
    public <T, R> Select(SerializedFunction<T, R> sf, FromItem fromItem) {
        this.delegate = new SelectItem(Environment.get(sf), fromItem);
    }
    
    public <T, R> Select(Function function, SerializedFunction<T, R> sf, FromItem fromItem) {
        this.delegate = new SelectItem(Functions.toMetaModelFunctionType(function), Environment.get(sf), fromItem);
    }
    
    public <T, R> Select(Function function, Object[] functionParameters, SerializedFunction<T, R> sf, FromItem fromItem) {
        this.delegate = new SelectItem(Functions.toMetaModelFunctionType(function), functionParameters, Environment.get(sf), fromItem);
    }
    
    public Select(Select subQuerySelectItem, FromItem subQueryFromItem) {
        this.delegate = new SelectItem(subQuerySelectItem.delegate, subQueryFromItem);
    }
    
    public Select setAlias(String alias) {
        this.delegate.setAlias(alias);
        return this;
    }
    
    public Select setQuery(Query query) {
        this.query = query;
        this.delegate.setQuery(query.getQuery());
        return this;
    }
    
    public Query getQuery() {
        return this.query;
    }
}
